package com.yyj.util.Http;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.MalformedURLException;
import java.net.Socket;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;

public class HTTP {
	
	private final static Logger log = LoggerFactory.getLogger(HTTP.class);
	
	public final static String POST_TYPE = "POST";
	public final static String GET_TYPE = "GET";

	/**
	 * 发送post请求
	 * 
	 * @param url
	 *            网址
	 * @param urlParam
	 *            参数
	 * @return 返回null时，标识服务器链接失败，详情查看getMsgInfo方法。
	 * @throws HTTPServiceException
	 */
	public static String POST(String url, Map<String, Object> urlParam)
			throws HTTPServiceException {
		log.info("请求地址:"+ url);
		log.info("请求参数:"+ JSON.toJSONString(urlParam));
		return POST(url, parseParam_to_string(urlParam, "p"));
	}

	/**
	 * 发送post请求
	 * 
	 * @param url
	 *            网址
	 * @param param
	 *            url参数格式的字符串（"key=value&k=v"）;
	 * @return 返回null时，标识服务器链接失败，详情查看getMsgInfo方法。
	 * @throws HTTPServiceException
	 */
	public static String POST(String url, String param)
			throws HTTPServiceException {
		log.info("请求地址:"+ url);
		log.info("请求参数:"+ JSON.toJSONString(param)) ;
		return sendBy(HTTP.POST_TYPE, url, param);// (url,
													// parseParam_to_map(param));
	}

	/**
	 * 发送get请求
	 * 
	 * @param url
	 * @param urlParam
	 * @return 返回null时，标识服务器链接失败，详情查看getMsgInfo方法。
	 * @throws HTTPServiceException
	 */
	public static String GET(String url, Map<String, Object> urlParam)
			throws HTTPServiceException {
		// return sendBy(GET_TYPE,url,parseParam_to_string(urlParam));
		String url_str = parseParam_to_string(urlParam, "p");
		return GET(url + "?" + url_str);
	}

	public static String GETByWechat(String url, Map<String, Object> urlParam)
			throws HTTPServiceException {
		String url_str = parseParam_to_string(urlParam, "p");
		return GET(url + "?" + url_str);
	}

	/**
	 * 发送get请求
	 * 
	 * @param urlWithParam
	 *            get方式请求的url：http://域名/?k=v&key=value
	 * @return 返回null时，标识服务器链接失败，详情查看getMsgInfo方法。
	 * @throws HTTPServiceException
	 */
	public static String GET(String urlWithParam) throws HTTPServiceException {
		/*
		 * int paramStartIndex = urlWithParam.indexOf("?"); String url =
		 * urlWithParam; String param_str = ""; if(paramStartIndex > 0){ url =
		 * urlWithParam.substring(0,paramStartIndex); param_str =
		 * urlWithParam.substring(paramStartIndex + 1); }
		 */

		return sendBy(HTTP.GET_TYPE, urlWithParam, "");// GET(url,
														// parseParam_to_map(param_str));
	}

	/**
	 * 判断指定服务器是否启动、开启服务等
	 * 
	 * @param url
	 * @return
	 */
	public static boolean testIsConnected(URL url) {
		boolean isConnected = true;
		try {
			int port = url.getPort();
			if (port == -1) {
				port = 80;
			}
			new Socket(url.getHost(), port);
		} catch (IOException e) {
			isConnected = false;
		}
		return isConnected;
	}

	/**
	 * 将map类型的对象 装换成url参数格式字符串
	 * 
	 * @param urlParam
	 * @return
	 */
	public static String parseParam_to_string(Map<String, Object> urlParam) {
		String param_str = "";
		if (urlParam != null) {
			Set<Entry<String, Object>> entrys = urlParam.entrySet();
			Iterator<Entry<String, Object>> entrys_interator = entrys
					.iterator();
			while (entrys_interator.hasNext()) {
				Entry<String, Object> entry = entrys_interator.next();

				String key = entry.getKey();
				String value = "";

				Object val = entry.getValue();
				if (val == null) {
					value = "";
				} else {
					if (val instanceof String) {
						value = val.toString();

					} else {
						value = JSON.toJSONString(val);
					}
				}

				param_str += key + "=" + value + "&";
			}
			int lastindex = param_str.lastIndexOf("&");
			param_str = param_str.substring(0, lastindex);
		}
		return param_str;
	}

	/**
	 * 将map类型的对象 装换成url参数格式字符串
	 * 
	 * @param urlParam
	 * @return
	 */
	public static String parseParam_to_string(Map<String, Object> urlParam,
			String jsontype) {
		String param_str = "";
		if (urlParam != null) {
			param_str += jsontype + "=";
			String json_ = "";
			Set<Entry<String, Object>> entrys = urlParam.entrySet();
			Iterator<Entry<String, Object>> entrys_interator = entrys
					.iterator();
			while (entrys_interator.hasNext()) {
				Entry<String, Object> entry = entrys_interator.next();

				String key = entry.getKey();
				String value = "";

				Object val = entry.getValue();
				if (val == null) {
					value = "";
				} else {
					if (val instanceof String) {
						value = val.toString();
					} else {
						value = val.toString();
					}
				}

				json_ += "\"" + key + "\":\"" + value + "\",";
			}
			int lastindex = json_.lastIndexOf(",");
			json_ = json_.substring(0, lastindex);
			param_str += "{" + json_ + "}";
		}
		return param_str;
	}

	/**
	 * 根据url查询字符串("key1=value1&key2=value2")构造map
	 * 
	 * @param param
	 * @return
	 */
	public static Map<String, Object> parseParam_to_map(String param) {
		Map<String, Object> result = null;
		int indexof = param.lastIndexOf("&");
		if (param != null && !"".equals(param)) {
			try {
				result = new HashMap<String, Object>();
				if (indexof == -1) {
					makeMap(param, result);
				} else {
					String[] entry_str = param.split("&");
					for (String ent : entry_str) {
						makeMap(ent, result);
					}
				}
			} catch (ArrayIndexOutOfBoundsException e) {
				result = null;
			}
		}
		return result;
	}

	/**
	 * 根据约定好的字符串("key=value")构造map
	 * 
	 * @param entry_str
	 * @param toMaked
	 *            ，要构造的map的引用
	 */
	private static void makeMap(String entry_str, Map<String, Object> toMaked) {
		String[] entry = entry_str.split("=");
		toMaked.put(entry[0], entry[1]);
		entry = null;
	}

	/**
	 * @param requestType
	 * @param url
	 * @param urlParam
	 * @return 返回null时，标识服务器链接失败。
	 * @throws HTTPServiceException
	 */
	private static String sendBy(String requestType, String url, String urlParam)
			throws HTTPServiceException {

		boolean isSuccess = false;

		String result = "";
		PrintWriter post_param = null;
		BufferedReader result_ = null;

		String msg_str = "";

		if (null == url || "".equals(url)) {
			throw new HTTPServiceException("URL 不能为空");
		}

		String param_ = urlParam + "&v=" + Math.random();
		if (GET_TYPE.equals(requestType.toUpperCase()) && !"".equals(param_)) {
			url += param_;
		}

		try {

			URL targetURL = new URL(url);
			if (testIsConnected(targetURL)) {
				URLConnection connection = targetURL.openConnection();
				connection.setRequestProperty("accept", "*/*");
				connection.setRequestProperty("connection", "Keep-Alive");
				connection
						.setRequestProperty("user-agent",
								"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");

				if (POST_TYPE.equals(requestType.toUpperCase())) { // post请求
					connection.setDoOutput(true);
					connection.setDoInput(true);

					post_param = new PrintWriter(new OutputStreamWriter(
							connection.getOutputStream(), "utf-8"));
					post_param.write(param_);
					post_param.flush();
				}

				connection.connect();

				InputStream io = connection.getInputStream();
				result_ = new BufferedReader(new InputStreamReader(io, "utf-8"));
				String read_temp = "";
				while ((read_temp = result_.readLine()) != null) {
					result += read_temp;
				}

				isSuccess = true;
			} else {
				msg_str = "链接服务器失败，请检查服务器";
				result = null;
			}
		} catch (MalformedURLException e) {
			e.printStackTrace();
			msg_str = "url错误" + e.toString();
		} catch (IOException e) {
			msg_str = "网络异常或参数错误" + e.toString();
		} catch (Exception e) {
			e.printStackTrace();
			msg_str = "exception:" + e.toString();
		} finally {
			post_param = null;
			result_ = null;
		}

		if (!isSuccess) {
			throw new HTTPServiceException(msg_str);
		}

		return result;
	}
}
